HAL CORDIC How to Use

group CORDIC_How_To_Use

How to use the CORDIC HAL module driver

  1. Declare a hal_cordic_handle_t handle structure and initialize the CORDIC driver with a CORDIC instance using HAL_CORDIC_Init(). HAL_CORDIC_Init() enables the CORDIC clock when USE_HAL_CORDIC_CLK_ENABLE_MODEL > HAL_CLK_ENABLE_NO.

  2. Configure the low-level hardware (CLOCK, NVIC, DMA…):

    • Enable the CORDICx interface clock unless you have set USE_HAL_CORDIC_CLK_ENABLE_MODEL > HAL_CLK_ENABLE_NO; in this case, HAL_CORDIC_Init() enables the clock.

    • NVIC configuration if you need to use interrupt processing:

    • DMA configuration if you need to use DMA processing:

      • Enable the DMAx interface clock.

      • Configure and enable two DMA channels, one for managing data transfer from memory to peripheral (input channel) and another channel for managing data transfer from peripheral to memory (output channel).

      • Associate the initialized DMA handle to the CORDIC DMA handle.

      • Configure the priority and enable the NVIC for the transfer complete interrupt on the two DMA channels by calling the HAL_CORTEX_NVIC_SetPriority() and HAL_CORTEX_NVIC_EnableIRQ() functions.

  3. Configure the minimum configuration needed for the CORDIC driver by calling HAL_CORDIC_SetConfig().

    • This function configures:

      • Processing functions: Cosine, Sine, Phase, Modulus, Arctangent, Hyperbolic cosine, Hyperbolic sine, Hyperbolic arctangent, Natural log, Square root.

      • Scaling factor: 1 to 2exp(-7).

      • Width of input data: 32-bit input data width (Q1.31 format) or 16-bit input data width (Q1.15 format).

      • Width of output data: 32-bit output data width (Q1.31 format) or 16-bit output data width (Q1.15 format).

      • Number of 32-bit writes expected for one calculation: One 32-bit write or two 32-bit writes.

      • Number of 32-bit reads expected after one calculation: One 32-bit read or two 32-bit reads.

      • Precision: 1 to 15 cycles for calculation (the more cycles, the better precision).

  4. Operation modes:

    • Polling mode operations:

      • The processing API is a blocking function, that is, it processes the data and waits until the output results are available. Perform this operation by calling HAL_CORDIC_Calculate().

    • Zero-overhead mode operations:

      • The processing API is a blocking function, that is, it writes data to process and reads the result immediately. Any attempt to read the result inserts a bus wait state until the calculation is completed. Perform this operation by calling HAL_CORDIC_CalculateZeroOverhead().

    • Interrupt mode operations:

      • The processing API is a non-blocking function, and an interrupt is generated whenever the output results are available. The result of the calculation is read in the interrupt service routine. However, it is slower than directly reading the result or polling the flag because of interrupt handling delays. Perform this operation by calling HAL_CORDIC_Calculate_IT().

      • When all the computations are done, HAL_CORDIC_CalculateCpltCallback() is executed. This callback is a weak function and can be overridden by the user or by registering a callback function.

      • In case of error during computation, the HAL_CORDIC_ErrorCallback() callback is executed. This callback is a weak function and can be overridden by the user or by registering a callback function.

    • DMA mode operations:

      • The processing API is a non-blocking function and allows offloading the CPU. If both channels are enabled, the CORDIC can autonomously perform repeated calculations on a buffer of data without any CPU access. Perform this operation by calling HAL_CORDIC_Calculate_DMA(). This function operates with a DMA channel In and a DMA channel out only.

      • The current DMA transfer can be cancelled using the HAL_CORDIC_Abort() or HAL_CORDIC_Abort_IT() functions.

      • When half of all the data are written, HAL_CORDIC_WriteHalfCpltCallback() is executed. This callback is a weak function and can be overridden by the user or by registering a callback function.

      • When half of all the results are read, HAL_CORDIC_ReadHalfCpltCallback() is executed. This callback is a weak function and can be overridden by the user or by registering a callback function.

      • When all the computations are done, HAL_CORDIC_CalculateCpltCallback() is executed. This callback is a weak function and can be overridden by the user or by registering a callback function.

      • In case of error during computation, the HAL_CORDIC_ErrorCallback() callback is executed. This callback is a weak function and can be overridden by the user or by registering a callback function.

  5. Write and read operations directly driven by another peripheral (Timer, ADC, DAC, etc) are available through:

    • Use the HAL_CORDIC_GetWriteAddress() and HAL_CORDIC_GetReadAddress() functions to get the addresses of the arguments and results as required by the user application.

    • Use HAL_CORDIC_Write_DMA() to manage the DMA write stream to the CORDIC peripheral, while the CORDIC customer peripheral (Timer, ADC, DAC, etc) is responsible for managing the corresponding DMA read stream through its dedicated DMA channel.

    • Use HAL_CORDIC_Read_DMA() to manage the DMA read stream to the CORDIC peripheral, while the CORDIC customer peripheral (Timer, ADC, DAC, etc) is responsible for managing the corresponding DMA write stream through its dedicated DMA channel.

  6. Call HAL_CORDIC_DeInit() to deinitialize the CORDIC peripheral.

  7. Call HAL_CORDIC_GetInstance() or HAL_CORDIC_GetLLInstance() to retrieve the CORDIC instance.

  8. Callback definition in Interrupt or DMA mode:

    When the preprocessor directive USE_HAL_CORDIC_REGISTER_CALLBACKS is set to 1, the user can dynamically configure the driver callbacks using their own method:

Callback name

Default value

Callback registration function

ErrorCallback

HAL_CORDIC_ErrorCallback

HAL_CORDIC_RegisterErrorCallback()

CalculationCpltCallback

HAL_CORDIC_CalculateCpltCallback

HAL_CORDIC_RegisterCalculateCpltCallback()

WriteDataCpltCallback

HAL_CORDIC_WriteCpltCallback

HAL_CORDIC_RegisterWriteCpltCallback()

AbortCpltCallback

HAL_CORDIC_AbortCpltCallback

HAL_CORDIC_RegisterAbortCpltCallback()

WriteHalfCpltCallback

HAL_CORDIC_WriteHalfCpltCallback

HAL_CORDIC_RegisterWriteHalfCpltCallback()

ReadHalfCpltCallback

HAL_CORDIC_ReadHalfCpltCallback

HAL_CORDIC_RegisterReadHalfCpltCallback()

To unregister a callback, register the default callback.

By default, after HAL_CORDIC_Init(), and when the state is HAL_CORDIC_STATE_INIT, all callbacks are set to the corresponding weak functions.

Callbacks can be registered in HAL_CORDIC_STATE_INIT or HAL_CORDIC_STATE_IDLE states only.

When the preprocessor directive USE_HAL_CORDIC_REGISTER_CALLBACKS is set to 0 or undefined, the callback registration feature is not available and all callbacks are set to the corresponding weak functions.